#!/bin/bash
###
# @Author: Logan.Li
# @Date: 2025-09-09 02:48:22
# @LastEditTime: 2025-09-09 02:48:22
# @Description: DNS服务部署脚本 - 基于dnsmasq实现轻量级DNS服务
###
# @支持系统: RHEL/CentOS/Rocky/AlmaLinux/Amazon Linux 2/Amazon Linux 2023/Debian/Ubuntu
###
# curl -s https://gitee.com/attacker/All-In-One-Ops/raw/master/1.scripts/services/dnsmasq.sh | bash

# 基础设置
set -e  # 遇到错误立即退出

# 路径定义
DOWNLOAD_DIR="/usr/local/src"    # 下载包存放路径
INSTALL_DIR="/opt"               # 服务安装路径  
ENV_DIR="/usr/local"             # 环境依赖路径
CONFIG_FILE="/etc/dnsmasq.conf" # DNS配置文件路径

# 简洁输出函数
info() { echo -e "\e[34m[INFO]\e[0m $1"; }
warn() { echo -e "\e[33m[WARN]\e[0m $1"; }
error() { echo -e "\e[31m[ERROR]\e[0m $1" >&2; }
success() { echo -e "\e[32m[SUCCESS]\e[0m $1"; }

# 判断是否root用户
if [ $(id -u) -ne 0 ]; then
    error "### This script must be run as root !!!"
    exit 1
fi

# 检测操作系统类型
detect_os() {
    if [ -f /etc/redhat-release ]; then
        OS="redhat"
        if command -v dnf &> /dev/null; then
            PKG_MANAGER="dnf"
        else
            PKG_MANAGER="yum"
        fi
    elif [ -f /etc/debian_version ]; then
        OS="debian"
        PKG_MANAGER="apt"
    else
        error "不支持的操作系统"
        exit 1
    fi
    info "检测到操作系统: $OS，包管理器: $PKG_MANAGER"
}

# 更新包管理器
update_package_manager() {
    info "更新包管理器..."
    case $PKG_MANAGER in
        "yum"|"dnf")
            $PKG_MANAGER update -y
            ;;
        "apt")
            apt update -y
            ;;
    esac
    success "包管理器更新完成"
}

# 安装dnsmasq
install_dnsmasq() {
    info "检查dnsmasq安装状态..."
    
    if command -v dnsmasq &> /dev/null; then
        success "dnsmasq 已安装"
        return 0
    fi
    
    warn "dnsmasq 未安装，开始安装..."
    info "dnsmasq安装过程包括："
    info "1. 使用系统包管理器安装dnsmasq"
    info "2. 创建配置文件备份"
    info "3. 配置基础DNS服务"
    info "4. 启动并设置开机自启"
    info ""
    
    case $PKG_MANAGER in
        "yum"|"dnf")
            $PKG_MANAGER install -y dnsmasq
            ;;
        "apt")
            apt install -y dnsmasq
            ;;
    esac
    
    success "dnsmasq 安装完成"
}

# 备份原配置文件
backup_config() {
    if [ -f "$CONFIG_FILE" ]; then
        info "备份原配置文件..."
        cp "$CONFIG_FILE" "${CONFIG_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
        success "配置文件已备份"
    fi
}

# 创建基础配置
create_basic_config() {
    info "创建基础DNS配置..."
    
    cat > "$CONFIG_FILE" << 'EOF'
# dnsmasq 基础配置文件
# 作者: Logan.Li
# 创建时间: $(date)

# 监听接口（0.0.0.0表示监听所有接口）
listen-address=127.0.0.1,0.0.0.0

# DNS端口
port=53

# 不读取/etc/hosts文件
no-hosts

# 不使用/etc/resolv.conf中的DNS服务器
no-resolv

# 上游DNS服务器配置
server=8.8.8.8
server=8.8.4.4
server=114.114.114.114

# 缓存大小
cache-size=1000

# 日志查询
log-queries

# 日志文件
log-facility=/var/log/dnsmasq.log

# 域名解析配置示例
# address=/example.local/192.168.1.100
# address=/test.local/192.168.1.101

# 禁止解析某些域名
# address=/ads.example.com/0.0.0.0

# 扩展配置目录
conf-dir=/etc/dnsmasq.d/,*.conf
EOF

    success "基础配置文件创建完成"
}

# 创建配置目录
create_config_dir() {
    info "创建配置目录..."
    mkdir -p /etc/dnsmasq.d
    
    # 创建示例配置文件
    cat > /etc/dnsmasq.d/custom.conf << 'EOF'
# 自定义DNS解析配置
# 格式: address=/域名/IP地址

# 示例配置（请根据需要修改）
# address=/internal.company.com/192.168.1.10
# address=/api.company.com/192.168.1.20
EOF
    
    success "配置目录创建完成"
}

# 创建日志目录
setup_logging() {
    info "设置日志..."
    touch /var/log/dnsmasq.log
    chmod 644 /var/log/dnsmasq.log
    
    # 配置logrotate
    cat > /etc/logrotate.d/dnsmasq << 'EOF'
/var/log/dnsmasq.log {
    daily
    missingok
    rotate 7
    compress
    notifempty
    create 644 root root
    postrotate
        systemctl reload dnsmasq > /dev/null 2>&1 || true
    endscript
}
EOF
    
    success "日志配置完成"
}

# 启动服务
start_service() {
    info "启动dnsmasq服务..."
    
    # 检查配置文件语法
    if ! dnsmasq --test; then
        error "配置文件语法错误，请检查配置"
        exit 1
    fi
    
    systemctl enable dnsmasq
    systemctl start dnsmasq
    
    if systemctl is-active --quiet dnsmasq; then
        success "dnsmasq服务启动成功"
    else
        error "dnsmasq服务启动失败"
        exit 1
    fi
}

# 显示服务状态
show_status() {
    info "DNS服务状态："
    systemctl status dnsmasq --no-pager -l
    
    info ""
    info "监听端口："
    netstat -tulnp | grep :53 || ss -tulnp | grep :53
}

# 显示配置提醒
show_config_reminder() {
    success "=== DNS服务安装完成 ==="
    info ""
    warn "重要提醒：请根据需要配置DNS解析规则"
    info ""
    info "主配置文件路径: $CONFIG_FILE"
    info "自定义配置目录: /etc/dnsmasq.d/"
    info "日志文件路径: /var/log/dnsmasq.log"
    info ""
    info "常用配置示例："
    info "1. 添加域名解析: address=/example.com/192.168.1.100"
    info "2. 屏蔽域名: address=/ads.example.com/0.0.0.0"
    info "3. 重载配置: systemctl reload dnsmasq"
    info "4. 查看日志: tail -f /var/log/dnsmasq.log"
    info ""
    info "测试DNS解析："
    info "nslookup google.com 127.0.0.1"
    info "dig @127.0.0.1 google.com"
    info ""
    warn "配置修改后请执行: systemctl reload dnsmasq"
}

# 主函数
main() {
    info "开始安装DNS服务..."
    info ""
    
    detect_os
    update_package_manager
    install_dnsmasq
    backup_config
    create_basic_config
    create_config_dir
    setup_logging
    start_service
    show_status
    show_config_reminder
    
    success "DNS服务部署完成！"
}

# 执行主函数
main "$@"
